home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Compilers⁄Interps / kevoSource / debug.c < prev    next >
Text File  |  1993-05-14  |  6KB  |  251 lines

  1. /* Kevo -- a prototype-based object-oriented language */
  2. /* (c) Antero Taivalsaari 1991-1993                   */
  3. /* Some parts (c) Antero Taivalsaari 1986-1988           */
  4. /* debug.c: Debugger internals and primitives           */
  5.  
  6. #include "global.h"
  7. #include "portGlobal.h"
  8.  
  9. /* --------------------------------------------------------------- */
  10.  
  11. /* This is an auxiliary operation which is not visible to the user */
  12. /* Print a bar which shows the current depth of the return stack */
  13. void showRSBar()
  14. {
  15.   int i;
  16.   int n = returnSp - returnStackBottom();
  17.   for (i = 1 ; i <= n; i++) {
  18.     if (i % 5) fprintf(confile, ">"); 
  19.     else fprintf(confile, "|");
  20.   }
  21. }
  22.  
  23.  
  24. /* This isn't user-accessible either */
  25. /* Print the contents of data and return stacks to console */
  26. void showStacks(string, inpair)
  27. char* string;
  28. PAIR* inpair;
  29. {
  30.     fprintf(confile, "%s '%s'\n", string, inpair->nfa);
  31.  
  32.     fprintf(confile, "\tData stack: ");
  33.     { 
  34.         int* ptr = dataStackBottom();
  35.         if (dataSp > dataStackBottom()) { 
  36.  
  37.             while (dataSp >= ++ptr) {
  38.                 PAIR* pair = findNameForward(*ptr);
  39.  
  40.                 if (pair) fprintf(confile, "%s ", pair->nfa);
  41.                 else {
  42.                     pair = findTypeForward(*ptr);
  43.                     if (pair) {
  44.                         fprintf(confile, "%s:", pair->nfa);
  45.                         fprintf(confile, "%d ", *ptr);
  46.                     }
  47.                     else fprintf(confile, "%d ", *ptr);
  48.                 }
  49.             }
  50.         }
  51.     }
  52.  
  53.     fprintf(confile, "\n\tReturn stack: "); 
  54.     {
  55.         int** ptr = returnStackBottom();
  56.           if (returnSp > returnStackBottom()) {
  57.               while (returnSp >= ++ptr) {
  58.                 PAIR* pair = findNameForward(maskedFetch(*ptr));
  59.  
  60.                 if (pair) { fprintf(confile, "%s ", pair->nfa); }
  61.                 else fprintf(confile, "%d ", (int)*ptr);
  62.               }
  63.           }
  64.       }
  65.  
  66.     fprintf(confile, "\n\tContext stack: "); 
  67.     {
  68.         int* ptr = (int*)contextStackBottom();
  69.         if (contextSp > contextStackBottom()) { 
  70.  
  71.             while ((int*)contextSp >= ++ptr) { 
  72.                   PAIR* pair = findTypeForward(*ptr);
  73.  
  74.                   if (pair) {
  75.                       fprintf(confile, "%s:", pair->nfa);
  76.                     fprintf(confile, "%d ", *ptr);
  77.                 }
  78.                 else {
  79.                     pair = findNameForward(*ptr);
  80.                     if (pair) fprintf(confile, "%s ", pair->nfa);
  81.                     else fprintf(confile, "%d ", *ptr);
  82.                 }
  83.             }
  84.         }
  85.     }
  86.  
  87.     fprintf(confile, "\n");
  88. }
  89.  
  90.  
  91. /* This is also inaccessible */
  92. /* Print the current process number to console */
  93. void showTaskID()
  94. {
  95.     fprintf(confile, " Task: %d ==\n", up);
  96. }
  97.  
  98.  
  99. /* --------------------------------------------------------------------------- */
  100. /* Here are the actual debugger primitives */
  101.  
  102. /* debugExit(): same as 'exit' but breaks and goes to shell. */
  103. /* Allows interactive debugging */
  104.    /* 
  105.      Note that there is only one longjump buffer and one set of debugger 
  106.      variables (defined in global.c). Thus only one task can be debugged
  107.      at a time, while other tasks will continue running normally. The
  108.      debug task is determined by the currently selected task (theTask)
  109.      in the system. After encountering a breakpoint, no other tasks can 
  110.      cause a breakpoint to happen, nor can they invoke 'resume'.
  111.    */
  112. void debugExit()
  113. {
  114.   PAIR* pair = findNameForward((OBJECT*)*(topReturn-1));
  115.  
  116.   /* 
  117.       Only one task can be debugged at a time. That task must 
  118.       currently have its input and output directed to a window
  119.       (rather than a file).
  120.   */
  121.   /* yyy warning: reference to 'theTask' is non-portable */
  122.  
  123.     if (!debugTask && up == theTask && infile == 0 && outfile == 0) {
  124.  
  125.         if (pair) {
  126.             showRSBar(); 
  127.             showStacks("Exiting", pair);
  128.         }
  129.         rpStore = returnSp;
  130.         debugTask = up;
  131.         execute(oShell);
  132.         (void)setjmp(debug);
  133.  
  134.         /* 'resume' command will resume execution here */
  135.  
  136.         if (!debugTask) {
  137.             returnSp = rpStore;
  138.             ip = (int**)popReturn();
  139.         }
  140.     }
  141.     else ip = (int**)popReturn();
  142. }
  143.  
  144.  
  145. /* Resume execution after 'debugExit' */
  146. /* Terminates the temporary shell and resets previous execution environment */
  147. void resume()
  148. {
  149.       /* 
  150.           Resume command will be accepted only from a task that has executed the
  151.          previous 'debugExit()' command
  152.       */
  153.     if (up == debugTask) {
  154.           debugTask = NIL;
  155.           longjmp(debug, TRUE);
  156.     }
  157. }
  158.  
  159.  
  160. /*---------------------------------------------------------------------------*/
  161. /* Inner interpreters/multitaskers for execution tracing */ 
  162.  
  163. /* An alternative inner interpreter: each time an operation is executed */
  164. /* its name will be printed to console */
  165.  
  166. void traceInterpreter()
  167. {
  168.   OBJECT* object;
  169.   PAIR*   pair;
  170.   int       count = 0;
  171.   TASK**  upStore = up;
  172.  
  173.   fprintf(confile, "== Trace mode activated ==\n");
  174.  
  175.   traceMode = TRACE;
  176.   supervisor = FALSE;
  177.   slice = (*up)->priority;
  178.  
  179.   while(TRUE) {
  180.       if (traceMode == QUITTRACE) ownLongJmp();
  181.  
  182.     if ((object = (OBJECT*)*ip++)->sfa) {    /* High-level definition */
  183.         pair = findNameForward(object);
  184.         if (pair) {
  185.             showRSBar(); 
  186.             fprintf(confile, "Entering '%s' (%d)\n", pair->nfa, count); 
  187.         }
  188.         pushReturn((int*)ip);
  189.         ip = (int**)(op = object)->mfa;
  190.     }
  191.     else {                                    /* Primitive definition */
  192.         pair = findPrimName((int*)object->mfa);
  193.         if (pair) {
  194.             showRSBar(); 
  195.             fprintf(confile, "Primitive '%s' (%d)\n", pair->nfa, count);
  196.         }
  197.         
  198.         ((void (*)())object->mfa)();
  199.  
  200.         if (--slice <= 0) yield();
  201.         if (up != upStore) fprintf(confile, "\n##### Task switch #####\n");
  202.         upStore = up;
  203.         EventLoop();    /* Call the event loop to enable better mouse control */
  204.     }
  205.  
  206.     /* Increment count every time inner interpreter proceeds */
  207.     count++;
  208.   }
  209. }
  210.  
  211.  
  212. /* An alternative inner interpreter: each time an operation is executed */
  213. /* its name and current stack contents will be printed to console */
  214.  
  215. void fullTraceInterpreter()
  216. {
  217.   OBJECT* object;
  218.   PAIR*   pair;
  219.   TASK**  upStore = up;
  220.  
  221.   fprintf(confile, "== Full trace mode activated ==\n");
  222.  
  223.   traceMode = FULLTRACE;
  224.   supervisor = FALSE;
  225.   slice = (*up)->priority;
  226.  
  227.   while(TRUE) {
  228.       if (traceMode == QUITTRACE) ownLongJmp();
  229.   
  230.     if ((object = (OBJECT*)*ip++)->sfa) {    /* High-level definition */
  231.         pair = findNameForward(object);
  232.         if (pair) showStacks("Entering", pair);
  233.  
  234.         pushReturn((int*)ip);
  235.         ip = (int**)(op = object)->mfa;
  236.     }
  237.     else {                                    /* Primitive definition */
  238.         pair = findPrimName((int*)object->mfa);
  239.         if (pair) showStacks("Primitive", pair);
  240.  
  241.         ((void (*)())object->mfa)();
  242.  
  243.         if (--slice <= 0) yield();
  244.         if (up != upStore) fprintf(confile, "\n##### Task switch #####\n\n");
  245.         upStore = up;
  246.         EventLoop();    /* Call the event loop to enable better mouse control */
  247.     }
  248.   }
  249. }
  250.  
  251.